package com.yyg.usecase.concurrent;

import org.junit.Test;

import java.util.concurrent.*;
import java.util.stream.IntStream;

/**
 * @Author: 冰岩
 * @Date: 2024/03/27
 * @Description:
 */
public class ThreadPoolExecutorTest {
    @Test
    public void ThreadPoolExecutorMonitorTest() {

        // 创建线程池
        ThreadFactory numberedThreadFactory = new NumberedThreadFactory("test");
        ExecutorService executorService = new ThreadPoolExecutor(10, 10, 10,
                java.util.concurrent.TimeUnit.SECONDS, new java.util.concurrent.LinkedBlockingQueue<>(2000)
                ,numberedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

        // 监控线程池
        int queueThreshold = 10;
        double activeRateThreshold = 0.8;
        Runnable monitorTask = () -> {
            ThreadPoolExecutor executor = (ThreadPoolExecutor)executorService;
            int maximumPoolSize = executor.getMaximumPoolSize();

            int activeCount = executor.getActiveCount();
            int largestPoolSize = executor.getLargestPoolSize();
            int queueSize = executor.getQueue().size();
            double historyMaxActiveRate = (double) largestPoolSize / maximumPoolSize;

            double activeRate = (double)activeCount / maximumPoolSize;
            boolean isOverLoad = activeRate > activeRateThreshold || queueSize > queueThreshold;
            if (isOverLoad) {
                String overLoadMsg = "queueSize: " + queueSize
                    + ", activeRate: " + activeRate
                    + ", historyMaxActiveRate: " + historyMaxActiveRate;
                System.out.println("warn: " + overLoadMsg);
            } else {
                String normalMsg = "queueSize: " + queueSize
                    + ", activeRate: " + activeRate
                    + ", historyMaxActiveRate: " + historyMaxActiveRate;
                System.out.println("info: " + normalMsg);
            }

        };
        ThreadFactory numberedThreadFactory4Scheduler = new NumberedThreadFactory("scheduler");
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, numberedThreadFactory4Scheduler);
        scheduledExecutorService.scheduleAtFixedRate(monitorTask, 0, 1, TimeUnit.SECONDS);

        // 提交任务
        IntStream.range(0, 30).forEach(i -> {
            executorService.submit(() -> {
                try {
                    Thread.sleep(2_000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        try {
            Thread.sleep(10_000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


    }

    @Test
    public void ThreadLocalTest() {
        ThreadLocal<String> threadLocal = new ThreadLocal<>();
        threadLocal.set("test");
        System.out.println(threadLocal.get());
    }

}
